package com.qf.core.utils;

import cn.idev.excel.*;
import cn.idev.excel.write.metadata.style.WriteCellStyle;
import cn.idev.excel.write.metadata.style.WriteFont;
import cn.idev.excel.write.style.HorizontalCellStyleStrategy;
import com.qf.core.annotation.ExcelColumn;
import com.qf.core.annotation.ExcelSheet;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @Author: sin
 * @Date: 2025/5/13 10:51
 * @Description: 自定义Excel 导入导出工具
 **/
public class CustomExcelUtil {

    private static <T> ByteArrayInputStream export(String fileName, List<T> dataList,Class<?> clazz) {
//        if (dataList == null || dataList.isEmpty()) {
//            return null;
//        }

        // 获取 ExcelSheet 注解中的 sheet 名称
        ExcelSheet sheetAnno = clazz.getAnnotation(ExcelSheet.class);
        String sheetName = StringUtils.isEmpty(fileName) ? (sheetAnno != null ? sheetAnno.name() : "Sheet1") : fileName;
            ;

        // 提取列定义并排序
        List<ColumnMapping> columnMappings = extractExcelColumns(clazz);

        // 构建表头，这里是一个 List<List<String>> 类型
        List<List<String>> headers = columnMappings.stream()
            .map(mapping -> Collections.singletonList(mapping.headerName))
            .collect(Collectors.toList());
        // 构建数据和表头映射
        List<List<Object>> rows = new ArrayList<>();
        for (T item : dataList) {
            List<Object> row = new ArrayList<>();
            for (ColumnMapping mapping : columnMappings) {
                try {
                    Object value = mapping.field.get(item);
                    row.add(value);
                } catch (IllegalAccessException e) {
                    row.add(null);
                }
            }
            rows.add(row);
        }
        // 使用 FastExcel 写入数据，确保表头已正确设置
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        FastExcel.write(outputStream, clazz)
                .registerWriteHandler(setStyle())
                .sheet(sheetName)
                .head(headers) // 这里传递的是 List<List<String>> 类型
            .doWrite(rows);
        // EasyExcel 有自动列宽
        return new ByteArrayInputStream(outputStream.toByteArray());
    }

    /** 提取注解字段及排序 */
    private static List<ColumnMapping> extractExcelColumns(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        List<ColumnMapping> mappings = new ArrayList<>();

        for (Field field : fields) {
            ExcelColumn columnAnno = field.getAnnotation(ExcelColumn.class);
            if (columnAnno != null) {
                field.setAccessible(true);
                mappings.add(new ColumnMapping(field, columnAnno.name(), columnAnno.order()));
            }
        }
        // 根据 order 字段排序，确保列顺序正确
        mappings.sort(Comparator.comparingInt(c -> c.order));
        return mappings;
    }

    /** 辅助类用于字段映射 */
    private static class ColumnMapping {
        Field field;
        String headerName;
        int order;

        public ColumnMapping(Field field, String headerName, int order) {
            this.field = field;
            this.headerName = headerName;
            this.order = order;
        }
    }
    /**
     * 设置表头和内容样式
     **/
    private static HorizontalCellStyleStrategy setStyle() {
        WriteCellStyle headStyle = new WriteCellStyle();
        WriteFont headFont = new WriteFont();
        headFont.setFontName("Microsoft YaHei UI");
        headFont.setFontHeightInPoints((short) 11);
        headStyle.setWriteFont(headFont);
        WriteCellStyle contentStyle = new WriteCellStyle();
        WriteFont contentFont = new WriteFont();
        contentFont.setFontName("Microsoft YaHei UI");
        contentFont.setFontHeightInPoints((short) 11);
        contentStyle.setWriteFont(contentFont);

        return new HorizontalCellStyleStrategy(headStyle, contentStyle);
    }
    public static ResponseEntity<byte[]> exportExcel(String fileName, List<?> data, Class<?> clazz) {
        ByteArrayInputStream inputStream = export(fileName, data, clazz);
        // 读取为字节数组
        byte[] bytes;
        bytes = inputStream.readAllBytes();
        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentDisposition(ContentDisposition.builder("attachment")
            .filename(fileName, StandardCharsets.UTF_8)
            .build());
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentLength(bytes.length);
        // 返回文件内容
        return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
    }
}
